#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>

// 线程同步：在保证数据一致的情况下，让多线程执行具有一定的顺序性

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int tickets = 1000;


//三个线程起来，竞争锁，没有成功在mutex后面排队

//场景 ： 当票被抢完以后，定期会放票
void *ThreadRun(void *args)
{
    std::string name = static_cast<const char *>(args);

    while (true)
    {
        pthread_mutex_lock(&mutex);
        if (tickets > 0)
        {
            usleep(1000);
            std::cout << name << " ,   tickets :   " << tickets-- << std::endl;
        }
        else  //在这里没有票了就不要反复去申请锁资源，什么事情都不做(浪费cpu资源)，而是去cond里面等待
        {
            std::cout << "没有票了" << std::endl;
            pthread_cond_wait(&cond, &mutex);
        }

        pthread_mutex_unlock(&mutex);
        // pthread_cond_wait(&cond,&mutex); //在等待的时候，该现线程需要释放当前拥有的锁资源
        // sleep(1); 注意这里没有sleep窝！
    }
    return nullptr;
}

//主线程

int main()
{
    pthread_t t1, t2, t3;
    pthread_create(&t1, nullptr, ThreadRun, (void *)"thread-1");
    pthread_create(&t1, nullptr, ThreadRun, (void *)"thread-2");
    pthread_create(&t3, nullptr, ThreadRun, (void *)"thread-3");

    while (true)
    {
        sleep(5);
        pthread_mutex_lock(&mutex);
        tickets += 100;
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond); // 一次唤醒一个线程，其余线程在cond条件变量后面排队，有特定的顺序
        // pthread_cond_broadcast(&cond); //一次唤醒全部线程，但是锁资源只有一个，当锁资源被占有的时候，其他线程去mutex下阻塞！！！
    }

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    return 0;
}